#pragma once
#include"usingHeader.hpp"


#define ERR_EXIT(m) \
do{\
perror(m);\
exit(EXIT_FAILURE);\
}while(0)

string pipe_name("transformer");
string delim("exit");


class fifo_pipe{
public:
    fifo_pipe(const string& path, const string& name)
        :_path(), _name(name), _real_file_pos(path + "/" + name)
    {
        int mk_fifo = mkfifo(_real_file_pos.c_str(), 0666);
        if(mk_fifo < 0) ERR_EXIT("server : mkfifo");
        else cout << "server : mkfifo success!" << endl;
        
        //server端接收client端的信息 -> 以只读的方式进行打开管道文件
        int fd = open(_real_file_pos.c_str(), O_RDONLY);
        if(fd < 0) ERR_EXIT("server : open fifo_pipe");
        else cout << "server : open fifo success!(O_RDONLY)" << endl;

    }

    ~fifo_pipe(){
        cout << "server : ready to delete fifo!" << endl;
        int ud = unlink(_real_file_pos.c_str());
        if(ud < 0) ERR_EXIT("server : delete fifo_pipe");
        else cout << "server : delete fifo success!" << endl;
    }
private:
    string _path;
    string _name;
    string _real_file_pos;
};


class fifo_operator{
public:
    fifo_operator(const string& path, const string& name)
        :_path(), _name(name), _real_file_pos(path + "/" + name)
    {}

    void Open_to_write(){
        int fd = open(_real_file_pos.c_str(), O_WRONLY | O_TRUNC);
        if(fd < 0) ERR_EXIT("open file(O_WRONLY | O_TRUNC)");
        else cout << "open file(O_WRONLY | O_TRUNC) success!" << endl;
        _fd = fd;
    }

    void Open_to_read(){
        int fd = open(_real_file_pos.c_str(), O_RDONLY);
        if(fd < 0) ERR_EXIT("open file(O_RDONLY)");
        else cout << "open file(O_RDONLY) success!" << endl;
        _fd = fd;
    }

    void Close(){
        cout << "going to be close fifo" << endl;
        int cd = close(_fd);
        if(cd < 0) ERR_EXIT("close fifo...");
        else cout << "close fifo success!" << endl;
    }

    int Wait(){
        char c = '\0';
        int rd = read(_fd, &c, 1);
        return rd;
    }

    void Wake(){
        char c = 'a';
        int wd = write(_fd, &c, 1);
        if(wd < 0) ERR_EXIT("wake(write)");
        else cout << "wake up success!" << endl;
    }

private:
    string _path;
    string _name;
    string _real_file_pos;
    int _fd;
};
